package com.doubao.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.doubao.common.result.Result;
import com.doubao.common.utils.OrderNumberUtil;
import com.doubao.user.client.PaymentClient;
import com.doubao.user.dto.MembershipOrderDTO;
import com.doubao.user.entity.MembershipLevel;
import com.doubao.user.entity.User;
import com.doubao.user.entity.UserMembership;
import com.doubao.user.mapper.MembershipLevelMapper;
import com.doubao.user.mapper.UserMapper;
import com.doubao.user.mapper.UserMembershipMapper;
import com.doubao.user.security.UserContext;
import com.doubao.user.service.MembershipService;
import com.doubao.user.service.MembershipSubscriptionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 会员订阅服务实现类
 */
@Service
@Slf4j
public class MembershipSubscriptionServiceImpl implements MembershipSubscriptionService {

    private final MembershipLevelMapper membershipLevelMapper;
    private final UserMembershipMapper userMembershipMapper;
    private final UserMapper userMapper;
    private final MembershipService membershipService;
    private final PaymentClient paymentClient;

    // 订阅类型对应的天数
    private static final Map<String, Integer> SUBSCRIPTION_DAYS = new HashMap<>();

    static {
        SUBSCRIPTION_DAYS.put("WEEKLY", 7);
        SUBSCRIPTION_DAYS.put("MONTHLY", 30);
        SUBSCRIPTION_DAYS.put("QUARTERLY", 90);
        SUBSCRIPTION_DAYS.put("YEARLY", 365);
        SUBSCRIPTION_DAYS.put("TEMP", 1);  // 临时2元卡，一天有效期
    }

    @Autowired
    public MembershipSubscriptionServiceImpl(
            MembershipLevelMapper membershipLevelMapper,
            UserMembershipMapper userMembershipMapper,
            UserMapper userMapper,
            MembershipService membershipService,
            PaymentClient paymentClient) {
        this.membershipLevelMapper = membershipLevelMapper;
        this.userMembershipMapper = userMembershipMapper;
        this.userMapper = userMapper;
        this.membershipService = membershipService;
        this.paymentClient = paymentClient;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<MembershipOrderDTO> createSubscriptionOrder(Long userId, Integer levelId,
                                                              String subscriptionType, String clientIp) {
        if (userId == null || levelId == null || subscriptionType == null) {
            return Result.failed("参数错误");
        }

        // 检查会员等级是否存在
        MembershipLevel level = membershipLevelMapper.selectById(levelId);
        if (level == null || level.getStatus() != 1) {
            return Result.failed("会员等级不存在或已禁用");
        }

        // 检查订阅类型是否有效
        if (!SUBSCRIPTION_DAYS.containsKey(subscriptionType)) {
            return Result.failed("无效的订阅类型");
        }

        // 获取用户信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            return Result.failed("用户不存在");
        }

        // 获取价格
        BigDecimal price = getPriceBySubscriptionType(level, subscriptionType);
        if (price == null) {
            return Result.failed("所选会员等级不支持该订阅类型");
        }

        // 价格转换为分
        int amount = price.multiply(BigDecimal.valueOf(100)).intValue();

        // 构建商品信息
        String subject = level.getName() + "-" + getSubscriptionTypeText(subscriptionType);
        String attach = "membershipOrder_" + levelId + "_" + subscriptionType;

        try {
            // 使用新的会员支付接口创建订单
            Result<Map<String, Object>> orderResult = paymentClient.createMembershipOrder(
                    userId, levelId.longValue(), amount, "jsapi", clientIp);

            if (!orderResult.isSuccess() || orderResult.getData() == null) {
                log.error("创建支付订单失败: {}", orderResult.getMessage());
                return Result.failed("创建支付订单失败: " + orderResult.getMessage());
            }

            // 获取支付订单数据
            Map<String, Object> paymentOrderData = orderResult.getData();
            String orderId = (String) paymentOrderData.get("orderId");

            // 创建会员订阅订单DTO
            MembershipOrderDTO orderDTO = new MembershipOrderDTO();
            orderDTO.setOrderId(orderId);
            orderDTO.setUserId(userId);
            orderDTO.setLevelId(levelId);
            orderDTO.setLevelName(level.getName());
            orderDTO.setSubscriptionType(subscriptionType);
            orderDTO.setPrice(price);
            orderDTO.setDays(SUBSCRIPTION_DAYS.get(subscriptionType));
            orderDTO.setCreatedAt(LocalDateTime.now());
            
            // 添加支付参数
            orderDTO.setPayInfo(paymentOrderData.get("payInfo"));

            return Result.success(orderDTO);
        } catch (Exception e) {
            log.error("创建会员订阅订单异常", e);
            return Result.failed("创建订单异常: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> handleSubscriptionPaySuccess(String orderId) {
        if (orderId == null || orderId.isEmpty()) {
            return Result.failed("订单ID不能为空");
        }

        try {
            log.info("【会员订阅】开始处理会员订阅支付成功回调: orderId={}", orderId);
            
            // 获取当前用户ID
            Long userId = UserContext.getUserId();
            if (userId == null) {
                log.error("【会员订阅】无法获取用户信息，尝试从订单获取用户ID");
                try {
                    // 尝试从订单中提取userId
                    log.info("【会员订阅】尝试从订单中获取用户ID: {}", orderId);
                    Result<Map<String, Object>> orderResult = paymentClient.queryMembershipOrder(orderId, 0L);
                    
                    if (!orderResult.isSuccess() || orderResult.getData() == null) {
                        log.error("【会员订阅】获取订单信息失败: {}", orderResult.getMessage());
                        return Result.failed("获取订单信息失败，请联系客服处理");
                    }
                    
                    Map<String, Object> responseData = orderResult.getData();
                    Map<String, Object> localOrder = (Map<String, Object>) responseData.get("localOrder");
                    
                    if (localOrder == null) {
                        log.error("【会员订阅】订单信息不完整，无法获取userId");
                        return Result.failed("订单信息不完整，无法处理");
                    }
                    
                    Object userIdObj = localOrder.get("userId");
                    if (userIdObj != null) {
                        if (userIdObj instanceof Integer) {
                            userId = ((Integer) userIdObj).longValue();
                        } else if (userIdObj instanceof Long) {
                            userId = (Long) userIdObj;
                        } else {
                            userId = Long.parseLong(userIdObj.toString());
                        }
                        log.info("【会员订阅】从订单中获取到用户ID: {}", userId);
                    } else {
                        log.error("【会员订阅】无法从订单中获取用户ID");
                        return Result.failed("订单用户信息缺失，无法处理");
                    }
                } catch (Exception e) {
                    log.error("【会员订阅】处理订单获取用户ID异常: {}", e.getMessage(), e);
                    return Result.failed("订单处理异常: " + e.getMessage());
                }
            }
            
            log.info("【会员订阅】处理会员订阅支付成功: userId={}, orderId={}", userId, orderId);
            
            // 使用新的会员订单查询接口
            log.info("【会员订阅】开始查询订单详情: userId={}, orderId={}", userId, orderId);
            Result<Map<String, Object>> orderResult = paymentClient.queryMembershipOrder(orderId, userId);
            if (!orderResult.isSuccess() || orderResult.getData() == null) {
                log.error("【会员订阅】获取订单信息失败: {}", orderResult.getMessage());
                return Result.failed("获取订单信息失败");
            }
            
            // 获取订单数据
            Map<String, Object> responseData = orderResult.getData();
            Map<String, Object> localOrder = (Map<String, Object>) responseData.get("localOrder");
            
            if (localOrder == null) {
                log.error("【会员订阅】订单信息不完整: {}", responseData);
                return Result.failed("订单信息不完整");
            }
            
            // 获取附加信息
            String attach = (String) localOrder.get("attach");
            log.info("【会员订阅】订单附加信息: {}", attach);
            if (attach == null || !attach.startsWith("membershipOrder_")) {
                log.error("【会员订阅】订单附加信息不正确: {}", attach);
                return Result.failed("订单信息不正确");
            }

            String[] parts = attach.split("_");
            if (parts.length < 3) {
                log.error("【会员订阅】订单附加信息格式不正确: {}", attach);
                return Result.failed("订单信息格式不正确");
            }

            Integer levelId;
            try {
                levelId = Integer.parseInt(parts[1]);
                log.info("【会员订阅】解析会员等级ID: {}", levelId);
            } catch (NumberFormatException e) {
                log.error("【会员订阅】会员等级ID格式错误: {}", parts[1]);
                return Result.failed("订单会员等级格式错误");
            }
            
            String subscriptionType = parts[2];
            log.info("【会员订阅】解析订阅类型: {}", subscriptionType);
            
            // 获取订阅天数
            Integer days = SUBSCRIPTION_DAYS.get(subscriptionType);
            if (days == null) {
                log.error("【会员订阅】无效的订阅类型: {}", subscriptionType);
                return Result.failed("无效的订阅类型");
            }
            log.info("【会员订阅】订阅天数: {}", days);
            
            // 获取状态信息
            String statusStr = (String) responseData.get("status");
            log.info("【会员订阅】订单状态: {}", statusStr);
            if (!"SUCCESS".equals(statusStr) && !"PAID".equals(statusStr)) {
                // 容忍PAID状态，视为支付成功
                log.info("【会员订阅】订单状态为 {}, 继续处理为支付成功", statusStr);
            }
            
            log.info("【会员订阅】准备创建会员: userId={}, levelId={}, 类型={}, 天数={}", 
                    userId, levelId, subscriptionType, days);
            
            // 创建或更新会员
            log.info("【会员订阅】调用会员服务创建/更新会员信息");
            Result<Void> membershipResult = membershipService.createMembership(
                    userId, levelId, subscriptionType, days, "payment", orderId);

            if (!membershipResult.isSuccess()) {
                log.error("【会员订阅】创建会员失败: {}", membershipResult.getMessage());
                return Result.failed("创建会员失败: " + membershipResult.getMessage());
            }

            log.info("【会员订阅】会员订阅支付成功处理完成: 订单={}, 用户={}, 等级={}, 类型={}",
                    orderId, userId, levelId, subscriptionType);

            return Result.success();
        } catch (Exception e) {
            log.error("【会员订阅】处理会员订阅支付成功异常: {}", e.getMessage(), e);
            return Result.failed("处理支付成功异常: " + e.getMessage());
        }
    }

    @Override
    public Result<Void> handleSubscriptionPayFailed(String orderId, String reason) {
        if (orderId == null || orderId.isEmpty()) {
            return Result.failed("订单ID不能为空");
        }

        try {
            // 使用Feign客户端关闭订单
            Result<Void> closeResult = paymentClient.closeOrder(
                    UserContext.getUserId(), orderId);
            
            if (!closeResult.isSuccess()) {
                log.error("关闭订单失败: {}", closeResult.getMessage());
                // 不返回失败，继续处理
            }

            log.info("会员订阅支付失败处理完成: 订单={}, 原因={}", orderId, reason);
            return Result.success();
        } catch (Exception e) {
            log.error("处理会员订阅支付失败异常", e);
            return Result.failed("处理支付失败异常: " + e.getMessage());
        }
    }

    @Override
    public Result<MembershipOrderDTO> getSubscriptionOrder(String orderId) {
        if (orderId == null || orderId.isEmpty()) {
            return Result.failed("订单ID不能为空");
        }

        try {
            // 获取当前用户ID
            Long userId = UserContext.getUserId();
            if (userId == null) {
                log.error("无法获取用户信息，无法查询订单");
                return Result.failed("用户未登录或认证信息丢失");
            }

            try {
                // 使用新的会员订单查询接口
                Result<Map<String, Object>> orderResult = paymentClient.queryMembershipOrder(orderId, userId);

                if (!orderResult.isSuccess() || orderResult.getData() == null) {
                    log.error("获取支付订单信息失败: {}", orderResult.getMessage());
                    return Result.failed("获取订单信息失败: " + orderResult.getMessage());
                }

                // 获取订单数据
                Map<String, Object> responseData = orderResult.getData();
                Map<String, Object> localOrder = (Map<String, Object>) responseData.get("localOrder");
                
                if (localOrder == null) {
                    return Result.failed("订单信息不完整");
                }
                
                // 获取附加信息
                String attach = (String) localOrder.get("attach");
                if (attach == null || !attach.startsWith("membershipOrder_")) {
                    log.error("订单附加信息不正确: {}", attach);
                    return Result.failed("订单信息不正确");
                }

                String[] parts = attach.split("_");
                if (parts.length != 3) {
                    log.error("订单附加信息格式不正确: {}", attach);
                    return Result.failed("订单信息格式不正确");
                }

                Integer levelId = Integer.parseInt(parts[1]);
                String subscriptionType = parts[2];

                // 获取会员等级信息
                MembershipLevel level = membershipLevelMapper.selectById(levelId);
                if (level == null) {
                    log.error("会员等级不存在: {}", levelId);
                    return Result.failed("会员等级不存在");
                }

                // 构建订单DTO
                MembershipOrderDTO orderDTO = new MembershipOrderDTO();
                orderDTO.setOrderId(orderId);
                orderDTO.setUserId((Long) localOrder.get("userId"));
                orderDTO.setLevelId(levelId);
                orderDTO.setLevelName(level.getName());
                orderDTO.setSubscriptionType(subscriptionType);
                
                Integer amount = (Integer) localOrder.get("amount");
                orderDTO.setPrice(BigDecimal.valueOf(amount).divide(BigDecimal.valueOf(100)));
                orderDTO.setDays(SUBSCRIPTION_DAYS.get(subscriptionType));
                
                // 设置订单状态
                String statusText = (String) responseData.get("status");
                orderDTO.setStatus(statusText != null ? statusText : "UNKNOWN");
                
                return Result.success(orderDTO);
            } catch (Exception ex) {
                log.error("调用微信支付服务异常: {}", ex.getMessage());
                return Result.failed("支付服务异常: " + ex.getMessage());
            }
        } catch (Exception e) {
            log.error("获取会员订阅订单异常", e);
            return Result.failed("获取订单异常: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> cancelSubscription(Long userId) {
        if (userId == null) {
            return Result.failed("用户ID不能为空");
        }

        try {
            // 获取用户当前会员信息
            LambdaQueryWrapper<UserMembership> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserMembership::getUserId, userId)
                    .eq(UserMembership::getStatus, 1)
                    .ge(UserMembership::getExpireTime, LocalDateTime.now());

            UserMembership membership = userMembershipMapper.selectOne(wrapper);
            if (membership == null) {
                return Result.failed("用户当前没有有效会员");
            }

            // 更新会员状态为取消
            membership.setStatus(0);
            membership.setUpdatedAt(LocalDateTime.now());
            userMembershipMapper.updateById(membership);

            // 更新用户VIP状态
            User user = userMapper.selectById(userId);
            if (user != null && user.getVipStatus() == 1) {
                user.setVipStatus(0);
                userMapper.updateById(user);
            }

            log.info("用户取消会员成功: userId={}, membershipId={}", userId, membership.getId());

            return Result.success();
        } catch (Exception e) {
            log.error("取消会员订阅异常", e);
            return Result.failed("取消订阅异常: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<MembershipOrderDTO> renewSubscription(Long userId, String subscriptionType, String clientIp) {
        if (userId == null || subscriptionType == null) {
            return Result.failed("参数错误");
        }

        try {
            // 获取用户当前会员信息
            LambdaQueryWrapper<UserMembership> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserMembership::getUserId, userId)
                    .eq(UserMembership::getStatus, 1)
                    .orderByDesc(UserMembership::getExpireTime)
                    .last("LIMIT 1");

            UserMembership membership = userMembershipMapper.selectOne(wrapper);
            if (membership == null) {
                return Result.failed("用户当前没有会员");
            }

            // 获取会员等级
            MembershipLevel level = membershipLevelMapper.selectById(membership.getLevelId());
            if (level == null) {
                return Result.failed("会员等级不存在");
            }

            // 创建订阅订单
            return createSubscriptionOrder(userId, level.getId(), subscriptionType, clientIp);
        } catch (Exception e) {
            log.error("续订会员异常", e);
            return Result.failed("续订会员异常: " + e.getMessage());
        }
    }

    /**
     * 根据订阅类型获取价格
     */
    private BigDecimal getPriceBySubscriptionType(MembershipLevel level, String subscriptionType) {
        switch (subscriptionType) {
            case "WEEKLY":
                return level.getPriceWeekly();
            case "MONTHLY":
                return level.getPriceMonthly();
            case "QUARTERLY":
                return level.getPriceQuarterly();
            case "YEARLY":
                return level.getPriceYearly();
            case "TEMP":
                return new BigDecimal("2.00"); // 临时卡固定价格
            default:
                return null;
        }
    }

    /**
     * 获取订阅类型文本
     */
    private String getSubscriptionTypeText(String subscriptionType) {
        switch (subscriptionType) {
            case "WEEKLY":
                return "周卡";
            case "MONTHLY":
                return "月卡";
            case "QUARTERLY":
                return "季卡";
            case "YEARLY":
                return "年卡";
            case "TEMP":
                return "临时卡";
            default:
                return subscriptionType;
        }
    }
}